﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.DataVisualization.Charting;
using System.Drawing;
using System.Collections.Specialized;
using System.IO;

namespace Microsoft.SPF.UI.WebControls
{
    [ToolboxData("<{0}:HistogramRangeRefinementControl runat=server></{0}:HistogramRangeRefinementControl>")]
    public class HistogramRangeRefinementControl : DivControl
    {

        private RefinementCollection refinementCollection;
        private RefinementCollection selectedRefinementCollection;
        protected Chart RangeChartControl;
        private Color cropColor;

        String selectedText;
        String chartImageUrl;
        String sliderInstanceName;

        #region Public プロパティ

        [Category("SPF")]
        public RefinementCollection RefinementCollection 
        {
            get
            {
                if (refinementCollection == null) refinementCollection = ViewState[UniqueID + "_refinements"] as RefinementCollection;
                if (refinementCollection == null) refinementCollection = new RefinementCollection();

                return refinementCollection;
            }
            set
            {
                ViewState[UniqueID + "_refinements"] = refinementCollection = value;
            }
        }

        [Category("SPF")]
        public Color BackColor
        {
            get;
            set;
        }

        [Category("SPF")]
        public String BackImage
        {
            get;
            set;
        }

        [Category("SPF")]
        public String BackImageWrapMode
        {
            get;
            set;
        }

        [Category("SPF")]
        public RefinementCollection SelectedRefinementCollection
        {
            get
            {
                RefinementCollection rc = refinementCollection = ViewState[UniqueID + "_refinements"] as RefinementCollection;

                if (rc == null)
                {
                    selectedRefinementCollection = new RefinementCollection();
                }
                else
                {
                    //TODO: Get selected refinements
                }

                return selectedRefinementCollection;
            }
        }

        [Category("SPF")]
        public HistogramType ChartType { get; set; }

        [Category("SPF")]
        public Boolean ShowLabel { get; set; }

        [Category("SPF")]
        public String Title { get; set; }

        [Category("SPF")]
        public String TitleCssClass { get; set; }

        [Category("SPF")]
        public String HistogramCssClass { get; set; }

        [Category("SPF")]
        public String LeftHistogramLayerCssClass { get; set; }

        [Category("SPF")]
        public String RightHistogramLayerCssClass { get; set; }

        [Category("SPF")]
        public String RightBarCssClass { get; set; }

        [Category("SPF")]
        public String LeftBarCssClass { get; set; }

        [Category("SPF")]
        public String RightSliderValueCssClass { get; set; }

        [Category("SPF")]
        public String LeftSliderValueCssClass { get; set; }

        [Category("SPF")]
        public String RightSliderId { get; set; }

        [Category("SPF")]
        public String LeftSliderId { get; set; }

        [Category("SPF")]
        public String SliderCssClass { get; set; }

        [Category("SPF")]
        public String SliderValueCssClass { get; set; }

        [Category("SPF")]
        public String RightSliderCssClass { get; set; }

        [Category("SPF")]
        public String LeftSliderCssClass { get; set; }

        [Category("SPF"), DefaultValue(70)]
        public int CropOpacity { get; set; }

        [Category("SPF")]
        public Color CropColor 
        {
            get
            {
                return cropColor;
            }
            set
            {
                if (cropColor == null) cropColor = Color.Red;
                cropColor = value;
            }
        }

        [Category("SPF")]
        public NameValueCollection ChartSeriesCustomProperties { get; set; }

        #endregion

        public String ManagedPropertyName { get; set; }

        public HistogramRangeRefinementControl()
        {
            //サイズ既定値
            Height = Unit.Pixel(300);
            Width = Unit.Pixel(400);
        }

        public String SliderInstanceName
        {
            get
            {
                return sliderInstanceName;
            }
        }



        protected override void OnPreRender(EventArgs e)
        {
            //系の作成
            Series series = CreateSeries();
            series.IsValueShownAsLabel = ShowLabel;

            #region データポイントの設定
            DataPoint dp;

            foreach (RefinementItem item in RefinementCollection)
            {
                dp = new DataPoint();
                dp.Url = item.Modifier;
                dp.ToolTip = item.Label;
                dp.SetValueY(item.Value);
                dp.Name = item.Modifier;

                if (String.IsNullOrEmpty(item.BackImage))
                {
                    dp.BackImage = BackImage;
                }
                else
                {
                    dp.BackImage = item.BackImage;
                }

                if (String.IsNullOrEmpty(item.BackImageWrapMode))
                {
                    if(!String.IsNullOrEmpty(BackImageWrapMode))
                    {
                        dp.BackImageWrapMode = (ChartImageWrapMode)Enum.Parse(typeof(ChartImageWrapMode), BackImageWrapMode);
                    }
                }
                else
                {
                    dp.BackImageWrapMode = (ChartImageWrapMode)Enum.Parse(typeof(ChartImageWrapMode),item.BackImageWrapMode);
                }

                series.Points.Add(dp);
            }

            #endregion

            ChartArea chartArea = new ChartArea();

            if (ShowLabel) chartArea.AxisY.Enabled = AxisEnabled.True; 

            chartArea.AxisX.MajorGrid.LineWidth = 0;    //線を非表示とする
            chartArea.AxisY.MajorGrid.LineWidth = 0;    
            chartArea.AxisY.IsMarksNextToAxis = false;  
            chartArea.AxisX.IsMarksNextToAxis = false;  
            chartArea.AxisY.LabelStyle.Enabled = false; //ラベルを非表示とする
            chartArea.AxisX.LabelStyle.Enabled = false;

            chartArea.Position.Auto = false;
            chartArea.Position.X = 0;
            chartArea.Position.Y = 0;
            chartArea.Position.Height = 100;
            chartArea.Position.Width = 100;

            chartArea.BackColor = System.Drawing.Color.FromArgb(234, 238, 241);
            chartArea.BorderColor = System.Drawing.Color.FromArgb(234, 238, 241);
            RangeChartControl.BackColor = System.Drawing.Color.FromArgb(234, 238, 241);

            RangeChartControl.ImageType = ChartImageType.Jpeg;
            RangeChartControl.ImageStorageMode = ImageStorageMode.UseImageLocation; 

            RangeChartControl.ChartAreas.Add(chartArea);
            
            RangeChartControl.Series.Add(series);
            chartImageUrl = RangeChartControl.CurrentImageLocation;

            RangeChartControl.IsMapEnabled = true;
            
            RegisterScript();

            base.OnPreRender(e);
        }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            //タイトル追加
            var title = new Label();
            title.Text = Title;
            title.CssClass = TitleCssClass;

            Controls.Add(title);
 
            if (RefinementCollection != null)
            {
                #region ヒストグラムコンテナ

                var histogramContainer = new DivControl();
                histogramContainer.CssClass = HistogramCssClass;

                LiteralControl leftLayer;
                if (!String.IsNullOrEmpty(LeftHistogramLayerCssClass))
                {
                    leftLayer = new LiteralControl("<div class=\"" + LeftHistogramLayerCssClass + "\"></div>");
                }
                else
                {
                    leftLayer = new LiteralControl("<div></div>");
                }

                LiteralControl rightLayer;
                if (!String.IsNullOrEmpty(RightHistogramLayerCssClass))
                {
                    rightLayer = new LiteralControl("<div class=\"" + RightHistogramLayerCssClass + "\"></div>");
                }
                else
                {
                    rightLayer = new LiteralControl("<div></div>");
                }

                histogramContainer.Controls.Add(RangeChartControl);
                histogramContainer.Controls.Add(leftLayer);
                histogramContainer.Controls.Add(rightLayer);

                Controls.Add(histogramContainer);

                #endregion

                #region スライドバーコンテナ

                var slidebarContainer = new DivControl();
                slidebarContainer.CssClass = SliderCssClass;

                LiteralControl leftBar;
                if (!String.IsNullOrEmpty(LeftBarCssClass))
                {
                    leftBar = new LiteralControl("<div class=\"" + LeftBarCssClass + "\"></div>");
                }
                else
                {
                    leftBar = new LiteralControl("<div></div>");
                }

                LiteralControl rightBar;
                if (!String.IsNullOrEmpty(RightBarCssClass))
                {
                    rightBar = new LiteralControl("<div class=\"" + RightBarCssClass + "\"></div>");
                }
                else
                {
                    rightBar = new LiteralControl("<div></div>");
                }

                LiteralControl leftSlider;
                if (!String.IsNullOrEmpty(LeftSliderCssClass))
                {
                    leftSlider = new LiteralControl("<div class=\"" + LeftSliderCssClass + "\"></div>");
                }
                else
                {
                    leftSlider = new LiteralControl("<div></div>");
                }

                LiteralControl rightSlider;
                if (!String.IsNullOrEmpty(RightSliderCssClass))
                {
                    rightSlider = new LiteralControl("<div class=\"" + RightSliderCssClass + "\"></div>");
                }
                else
                {
                    rightSlider = new LiteralControl("<div></div>");
                }

                slidebarContainer.Controls.Add(leftBar);
                slidebarContainer.Controls.Add(rightBar);
                slidebarContainer.Controls.Add(leftSlider);
                slidebarContainer.Controls.Add(rightSlider);

                Controls.Add(slidebarContainer);

                #endregion

                #region スライドバー値コンテナ

                var slidebarValueContainer = new DivControl();
                slidebarValueContainer.CssClass = SliderValueCssClass;

                LiteralControl leftBarValue;
                if (!String.IsNullOrEmpty(LeftSliderValueCssClass))
                {
                    leftBarValue = new LiteralControl("<div id=\"" + LeftSliderId + "\" class=\"" + LeftSliderValueCssClass + "\"></div>");
                }
                else
                {
                    leftBarValue = new LiteralControl("<div id=\"" + LeftSliderId + "\"></div>");
                }

                LiteralControl rightBarValue;
                if (!String.IsNullOrEmpty(RightSliderValueCssClass))
                {
                    rightBarValue = new LiteralControl("<div id=\"" + RightSliderId + "\" class=\"" + RightSliderValueCssClass + "\"></div>");
                }
                else
                {
                    rightBarValue = new LiteralControl("<div id=\"" + RightSliderId + "\"></div>");
                }

                slidebarValueContainer.Controls.Add(leftBarValue);
                slidebarValueContainer.Controls.Add(rightBarValue);

                slidebarValueContainer.Controls.Add(new LiteralControl("<div id=\"leftRawValue\" style=\"display:none\"></div>"));
                slidebarValueContainer.Controls.Add(new LiteralControl("<div id=\"rightRawValue\" style=\"display:none\"></div>"));

                Controls.Add(slidebarValueContainer);

                #endregion
            }
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            if (RangeChartControl == null)
            {
                RangeChartControl = new Chart();
            }


            RangeChartControl.Width = Width;
            RangeChartControl.Height = Unit.Pixel((Int32)Height.Value - 25);
            

            RangeChartControl.ID = "HistogramImage";
            RangeChartControl.RenderType = RenderType.ImageTag;

            sliderInstanceName = ClientID + "Instance";
        }

        protected virtual String BuildStartupScript()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("var PointsGrid1 = new Array();");
            sb.AppendLine("var DatsGrid1 = new Array();");

            sb.Append("mapToGrid1('");
            sb.Append(RangeChartControl.ClientID);
            sb.AppendLine("ImageMap');");
            sb.AppendLine();

            // スライダーの初期化
            sb.AppendLine("var " + sliderInstanceName + " = new cSlider('" + ClientID + "', PointsGrid1, DatsGrid1, 0, -1, '"+ManagedPropertyName+"');");
            sb.AppendLine();

            return sb.ToString();
        }

        protected virtual void RegisterScript()
        {
            Page.ClientScript.RegisterClientScriptResource(this.GetType(),
                "Microsoft.SPF.UI.WebControls.js.sliders_engine.js");

            Page.ClientScript.RegisterStartupScript(this.GetType(),
                "HistogramRangeRefinementStartup_" + ClientID,
			    BuildStartupScript(),
                true);
        }

        private Series CreateSeries()
        {
            Series series = new Series();

            switch (ChartType)
            {
                case HistogramType.Bar:
                    series.ChartType = SeriesChartType.Bar;
                    break;

                case HistogramType.Line:
                    series.ChartType = SeriesChartType.Line;
                    break;

                default:
                    series.ChartType = SeriesChartType.Column;
                    break;
            }

            return series;
        }
    }
}
